package main

import "sort"

// twoSum 哈希--两数之和
// 函数功能：在给定整数数组nums中找出两个数，使它们的和等于目标值target
// 参数：
//
//	nums: 整数数组
//	target: 目标值
//
// 返回值：
//
//	包含两个索引的切片，这两个索引对应的元素之和等于target
//	如果没有找到符合条件的两个数，返回nil
func twoSum(nums []int, target int) []int {
	// 创建哈希表用于存储数值和对应的索引
	hasTable := map[int]int{}

	// 遍历数组
	for i, x := range nums {
		// 检查哈希表中是否存在与当前元素x相加等于target的值
		if p, ok := hasTable[target-x]; ok {
			// 如果存在，返回这两个数的索引
			return []int{p, i}
		}
		// 将当前数值和索引存入哈希表
		hasTable[x] = i
	}
	// 遍历结束仍未找到符合条件的两个数，返回nil
	return nil
}

// groupAnagrams 哈希--字母异位词分组
// 函数功能：将字符串数组中的字符串分组，使得每个组中的字符串都是字母异位词
// 参数：
//
//	strs: 字符串数组
//
// 返回值：
//
//	字符串数组的二维切片，每个切片中的字符串都是字母异位词
//	如果没有字母异位词，返回一个空切片
func groupAnagrams(strs []string) [][]string {
	// 创建一个映射，键是排序后的字符串，值是原始字符串的切片
	mp := map[string][]string{}

	// 遍历输入的字符串切片
	for _, str := range strs {
		// 将字符串转换为字节切片以便排序
		s := []byte(str)
		// 对字节切片进行排序
		sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
		// 将排序后的字节切片转换回字符串作为键
		sortedStr := string(s)
		// 将原始字符串添加到对应键的切片中
		mp[sortedStr] = append(mp[sortedStr], str)
	}

	// 创建结果切片，容量设置为映射的大小以提高效率
	ans := make([][]string, 0, len(mp))
	// 遍历映射的值，将每个分组添加到结果切片中
	for _, v := range mp {
		ans = append(ans, v)
	}

	// 返回分组后的结果
	return ans
}

func main() {
	into := twoSum([]int{2, 7, 11, 15}, 9)
	println(into[0], into[1])

	group := groupAnagrams([]string{"eat", "tea", "tan", "ate", "nat", "bat"})
	println(group)
}
